!> author: 左志华
!> date: 2022-07-04
!>
!> Use Meson to run this app. <br>
!> 使用 Meson 运行程序: `> meson setup _build && meson compile -C _build`
program main

    use seakeeping_string, only: to_string
    use seakeeping_time, only: tic, toc, now
    use seakeeping_filesystem, only: operator(.join.), is_exist
    use sph_kinds, only: rk
    use sph_load_toml, only: parse_project_toml
    use sph_project_type, only: project_t
    use sph_region, only: region_t
    use sph_time_integration, only: time_integration
    use sph_load_pif, only: load_particle_information
    use sph_save_pif, only: handle_PIF, save_PIF, nstep
    use sph_save_pif, only: save_acc
    use sph_eos, only: eos_type
    use sph_internal_force, only: viscosity
    use sph_density_summation, only: density_summation_type
    use sph_navier_stokes_solver, only: dt
    use sph_env, only: nums, hsml, dim
    use sph_command_line, only: cli, command_line
    use sph_terminal, only: term
    use sph_smoothed_kernel_function, only: skf
    type(region_t) :: region  !! 模拟域
    type(project_t) :: project  !! 工程设置
    integer :: steps, nstart = 1
    real(rk) :: time_start = 0.0_rk  !! 开始时间
    integer :: stat, seed  !! 时间记录

    ! ------------------------- 读取文件和配置方法 ---------------------------- !
    call tic(seed=seed)
    call term%setup()
    call cli%parse()
    open (99, file=cli%working_directory.join.'sph.txt', status='replace')

    print "(A)", "Smooth Particle Hydrodynamics Calculations, Ti-SPH v0.3.5"
    print "(/A)", "*** Read files and configure methods"
    call parse_project_toml(project, cli%working_directory)
    call load_particle_information(project%path, region, nums, project%go_on, project%go_on_step, hsml) ! @todo 检查 tmpin 文件夹是否存在
    call project%set_methods(region, hsml)
    call handle_PIF(project%fid, project%name, region, h5part_file=project%path.join."pif-out.h5part")
    if (.not. project%go_on) call save_PIF(project%fid, region, dim, nums(4), dt, nstep)

    ! --------------------------- 显示项目信息 ------------------------------- ！
    print "(/'*** Summary of project and solver information')"
    call term%info("Project name: "//project%name)
    print "(a,t40,g0.4)", "Time step (s): ", dt
    print "(a,t40,i0)", "Density summation type: ", density_summation_type
    print "(a,t40,i0)", "EoS type: ", eos_type
    print "(a,t40,l1)", "Viscosity: ", viscosity
    print "(a,t40,a)", "Smoothed kernel: ", skf%type
    print "(a,t40,l1)", "Save acceleration: ", save_acc
    print "(a,t40,i0)", "OMP threads: ", cli%num_threads
    print "(a,t40,i0)", "Number of particles: ", nums(1)

    ! ---------------------------- 进入主循环 ------------------------------- ！
    print "(/'*** Solving the main loop')"
    write (99, '(a)') 'NOPP(粒子对数目), ANOP(+)(平均粒子对数目，含自身)'

    main_loop: do
        if (cli%nsteps < 0) then
            write (*, '(a)', advance='no') "Enter the number of time steps &
                &(enter a negative number or other type to exit): "
            read (*, *, iostat=stat) steps
        else
            steps = cli%nsteps
            stat = 0
        end if
        if (steps < 0 .or. stat /= 0) then
            print '(a)', 'Exitting ...'
            exit main_loop
        end if
        call time_integration(project, region, nstart, steps, time_start, dt)
        nstart = nstart + steps
        time_start = time_start + steps*dt
        print *, ''
        call term%success("Completed calculation in stages! &
            &Stored time steps of particle information: "//to_string(int(nstep) - 1,'i0'))
        if (cli%nsteps >= 0) exit
    end do main_loop

    ! ----------------------------- 程序结束 ------------------------------- ！
    call handle_PIF(project%fid, project%name, region, close=.true.)
    close (99)
    call time_used_per_10thousand_steps()
    print "(/A)", 'All done! Thanks for using Ti-SPH!'
    call toc(seed=seed, t=now())
contains
    subroutine time_used_per_10thousand_steps()
        real(rk) :: t
        call toc(seed=seed, t=t)
        t = t/nstart*10000.0_rk
        print "(a,t40,g0.4)", "Time used per 10,000 steps (s): ", t
    end subroutine time_used_per_10thousand_steps
end program main
